package com.yzz.composeweatherproject.activity

import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.*
import androidx.compose.animation.core.*
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension
import androidx.lifecycle.lifecycleScope
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.rememberPagerState
import com.yzz.composeweatherproject.activity.ui.theme.ComposeWeatherProjectTheme

class AnimationActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeWeatherProjectTheme {
                // A surface container using the 'background' color from the theme
//                PressIconButton({}, {
//                    Icon(Icons.Filled.ShoppingCart, contentDescription = null)
//                }, { Text(text = "加入购物车") })
//                BottomNavigationView()
                view()
//                BottomNavigationView()
            }
        }
    }

    @OptIn(ExperimentalPagerApi::class)
    @Composable
    private fun view() {

        val list: MutableList<CustomBottomType> =
            mutableListOf(
                CustomBottomType("首页", Icons.Default.Home, CustomBottomEnum.HOME),
                CustomBottomType("内容", Icons.Default.Info, CustomBottomEnum.CONTENT),
                CustomBottomType("设置", Icons.Default.Settings, CustomBottomEnum.SETTING),
                CustomBottomType("设置", Icons.Default.Settings, CustomBottomEnum.SETTING),
                CustomBottomType("设置", Icons.Default.Settings, CustomBottomEnum.SETTING),
            )
        var customBottomType: CustomBottomType by remember {
            mutableStateOf(list[0])
        }
        var customBottomClickIndex by remember {
            mutableStateOf(0)
        }
        ConstraintLayout(modifier = Modifier
            .fillMaxSize()
            .clickable { }
        ) {
            val (bo, content) = createRefs()

            val pageState = rememberPagerState()
            LaunchedEffect(key1 = customBottomClickIndex) {
                pageState.scrollToPage(customBottomClickIndex)
            }

            HomePage(list = list,
                state = pageState,
                modifier = Modifier.constrainAs(content) {
                    top.linkTo((parent.top))
                    bottom.linkTo(bo.top)
                    centerHorizontallyTo(parent)
                    width = Dimension.fillToConstraints
                    height = Dimension.fillToConstraints
                })

            CustomBottom(list, modifier = Modifier.constrainAs(bo) {
                bottom.linkTo(parent.bottom)
                centerHorizontallyTo(parent)
            }) { index, type ->
                customBottomClickIndex = index
                customBottomType = type
            }

        }
    }

    @OptIn(ExperimentalAnimationApi::class)
    @Composable
    fun Greeting4(name: String) {
        var editable by remember { mutableStateOf(true) }
        val density = LocalDensity.current
        Column {
            AnimatedVisibility(visible = editable) {
                Text(
                    text = "asdasdsad",
                )
            }
            AnimatedVisibility(visible = editable,
                enter = slideInVertically {
                    with(density) { -40.dp.roundToPx() }
                } + expandVertically(expandFrom = Alignment.Top)
                        + fadeIn(initialAlpha = 0.3f),
                exit = slideOutVertically() + shrinkVertically() + fadeOut()
            ) {
                Text(
                    text = "Hello $name!Hello $name!Hello $name!Hello $name!Hello $name!Hello $name!Hello $name!Hello $name!Hello $name!Hello $name!",
                )
            }
            var textString by remember {
                mutableStateOf("")
            }
            var currentPage by remember { mutableStateOf("A") }

            Button(onClick = {
                textString += "aaaaaaa"
                currentPage = "B"
                editable = !editable
            }, modifier = Modifier.animateContentSize { initialValue, targetValue ->
                Log.d("yyzzsize", "initialValue=$initialValue")
                Log.d("yyzzsize", "targetValue=$targetValue")
            }) {
                Text(text = textString)
            }
            Crossfade(targetState = currentPage) { screen ->
                when (screen) {
                    "A" -> Text("Page A")
                    "B" -> Text("Page B")
                }
            }
            val alpha: Float by animateFloatAsState(if (editable) 1f else 0.5f)
            Box(Modifier
                .size(50.dp)
                .graphicsLayer(alpha = alpha)
                .background(Color.Red))
            //根据 `editable` 从灰色开始并动画到绿色
            val color = remember {
                Animatable(Color.Gray)
            }
            LaunchedEffect(editable) {
                color.animateTo(if (editable) Color.Green else Color.Red)
            }
            Box(modifier = Modifier
                .size(50.dp)
                .background(color.value))

            //updateTransition创建并记住一个实例Transition并更新其状态。
            var currentState by remember {
                mutableStateOf(BoxState.Collapsed)
            }
            val transition = updateTransition(targetState = currentState, label = "")
            //然后，您可以使用animate*扩展函数之一在此过渡中定义子动画。
            val rect by transition.animateRect(label = "") { state ->
                when (state) {
                    BoxState.Expanded -> Rect(0f, 0f, 100f, 100f)
                    BoxState.Collapsed -> Rect(100f, 100f, 300f, 300f)
                }
            }

            val borderWidth by transition.animateDp(label = "") { state ->
                when (state) {
                    BoxState.Expanded -> 20.dp
                    BoxState.Collapsed -> 80.dp
                }
            }


            val color2 by transition.animateColor(transitionSpec = {
                when {
                    BoxState.Expanded isTransitioningTo BoxState.Collapsed ->
                        spring(stiffness = 50f)
                    else ->
                        tween(durationMillis = 2000)
                }
            }, label = "") { state ->
                when (state) {
                    BoxState.Collapsed -> MaterialTheme.colors.onSurface
                    BoxState.Expanded -> MaterialTheme.colors.error
                }
            }

            Box(modifier = Modifier
                .size(borderWidth)
                .background(color2)
                .clickable {
                    BoxState
                        .values()
                        .forEach {
                            if (currentState != it) {
                                currentState = it

                                return@clickable
                            }
                        }
                })

            Row {
                var count by remember { mutableStateOf(0) }
                Button(onClick = { count++ }) {
                    Text(text = "加")
                }
                Button(onClick = { count-- }) {
                    Text(text = "减")
                }
                AnimatedContent(targetState = count, transitionSpec = {
                    // 将传入号码与前一个号码进行比较。
                    if (targetState > initialState) {
                        // 如果目标数字较大，它会向上滑动并淡入，而初始（较小的）数字会向上滑动并淡出。
                        slideInVertically { height -> height } + fadeIn() with
                                slideOutVertically { height -> -height } + fadeOut()
                    } else {
                        // 如果目标数字较小，则向下滑动并淡入，而初始数字向下滑动并淡出。
                        slideInVertically { height -> -height } + fadeIn() with
                                slideOutVertically { height -> height } + fadeOut()
                    }.using(
                        // 禁用剪辑，因为淡入淡出的滑出应该显示在边界之外。
                        SizeTransform(clip = false)
                    )
                }) { targetState ->
                    Text(text = "count=$targetState")
                }
            }


        }


    }

    enum class DialerState { DialerMinimized, NumberPad }

    @Composable
    fun DialerButton(isVisibleTransition: Transition<Boolean>) {
        // `isVisibleTransition` 使内容无需了解其他 DialerStates。
// 相反，内容可以专注于动画可见和不可见之间的状态变化。

    }


    @Composable
    fun NumberPad(isVisibleTransition: Transition<Int>) {
        // `isVisibleTransition 不需要内容了解其他 DialerStates。
// 相反，内容可以专注于动画可见和不可见之间的状态变化。
        val theDp = isVisibleTransition.animateDp(label = "") { state ->
            when (state) {
                3 -> {
                    20.dp
                }
                4 -> {
                    10.dp
                }
                else -> {
                    30.dp
                }
            }
        }

    }

    @OptIn(ExperimentalMaterialApi::class, ExperimentalAnimationApi::class)
    @Composable
    private fun changeView() {
        var expanded by remember { mutableStateOf(false) }
        Surface(
            color = MaterialTheme.colors.primary,
            onClick = { expanded = !expanded }
        ) {
            AnimatedContent(
                targetState = expanded,
                transitionSpec = {
                    fadeIn(animationSpec = tween(150, 150)) with
                            fadeOut(animationSpec = tween(150)) using
                            SizeTransform { initialSize, targetSize ->
                                if (targetState) {
                                    keyframes {
                                        // Expand horizontally first.
                                        IntSize(targetSize.width, initialSize.height) at 150
                                        durationMillis = 300
                                    }
                                } else {
                                    keyframes {
                                        // Shrink vertically first.
                                        IntSize(initialSize.width, targetSize.height) at 150
                                        durationMillis = 300
                                    }
                                }
                            }
                }
            ) { targetExpanded ->
                if (targetExpanded) {
                    Text(text = "Selected")
                } else {
                    Icon(imageVector = Icons.Default.Phone, contentDescription = "Phone")
                }
            }
        }
    }

    @Composable
    private fun InfiniteTransition() {
        val infiniteTransition = rememberInfiniteTransition()
        val color by infiniteTransition.animateColor(
            initialValue = Color.Red,
            targetValue = Color.Green,
            animationSpec = infiniteRepeatable(
                animation = tween(1000, easing = LinearEasing),
                repeatMode = RepeatMode.Reverse
            )
        )
        Box(Modifier
            .fillMaxSize()
            .background(color))
    }

    @Composable
    private fun TargetBasedAnimation() {
        val anim = remember {
            TargetBasedAnimation(
                animationSpec = tween(200),
                typeConverter = Float.VectorConverter,
                initialValue = 200f,
                targetValue = 1000f
            )
        }
        var playTime by remember {
            mutableStateOf(0L)
        }
        var animationValue by remember {
            mutableStateOf(0f)
        }
        LaunchedEffect(anim) {
            val startTime = withFrameNanos { it }
            do {
                playTime = withFrameNanos { it } - startTime
                animationValue = anim.getValueFromNanos(playTime)
                Log.d("yyzzanimate", "$animationValue")
            } while (animationValue < 1000f)
        }
        Text(text = "$animationValue")
    }

    @OptIn(ExperimentalTransitionApi::class)
    @Composable
    fun Dialer(dialerState: DialerState) {
        val transition: Transition<DialerState> = updateTransition(dialerState, label = "")
        Box {
            // 为数字键盘和尿布按钮创建单独的布尔类型的子转换，用于可见和不可见之间的任何内容动画
            NumberPad(
                transition.createChildTransition {
                    when (it) {
                        DialerState.NumberPad -> {
                            return@createChildTransition 3
                        }
                        DialerState.DialerMinimized -> {
                            return@createChildTransition 4
                        }
                    }
                }
            )
            DialerButton(
                transition.createChildTransition {
                    it == DialerState.DialerMinimized
                }
            )
        }
    }

    enum class BoxState {
        Collapsed,
        Expanded
    }

    @OptIn(ExperimentalAnimationApi::class, ExperimentalMaterialApi::class)
    @Composable
    fun AnimatedVisibilityAndAnimatedContentWithTransition() {
        var selected by remember { mutableStateOf(false) }
// Animates changes when `selected` is changed.
        val transition = updateTransition(selected, label = "")
        val borderColor by transition.animateColor(label = "") { isSelected ->
            if (isSelected) Color.Magenta else Color.White
        }
        val elevation by transition.animateDp(label = "") { isSelected ->
            if (isSelected) 10.dp else 2.dp
        }
        Surface(
            onClick = { selected = !selected },
            shape = RoundedCornerShape(8.dp),
            border = BorderStroke(2.dp, borderColor),
            elevation = elevation
        ) {
            Column(modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp)) {
                Text(text = "Hello, world!")
                // AnimatedVisibility 作为过渡的一部分。
                transition.AnimatedVisibility(
                    visible = { targetSelected -> targetSelected },
                    enter = expandVertically(),
                    exit = shrinkVertically()
                ) {
                    Text(text = "It is fine today.")
                }
                // AnimatedContent 作为过渡的一部分。
                transition.AnimatedContent { targetState ->
                    if (targetState) {
                        Text(text = "Selected")
                    } else {
                        Icon(imageVector = Icons.Default.Phone, contentDescription = "Phone")
                    }
                }
            }
        }
    }

    @Composable
    private fun baseAnimation() {
        var enabled by remember {
            mutableStateOf(false)
        }
        val tweenValue: Float by animateFloatAsState(targetValue = if (enabled) 1f else 0.5f,
            // 配置动画持续时间和缓动。
            animationSpec = tween(durationMillis = 300,
                delayMillis = 50, easing = LinearEasing)
        )

        val springValue by animateFloatAsState(targetValue = if (enabled) 0.5f else 1f,
            animationSpec = spring(
                dampingRatio = Spring.DampingRatioNoBouncy,
                stiffness = Spring.StiffnessMedium
            ))
        val keyframesValue by animateFloatAsState(targetValue = if (enabled) 0.5f else 1f,
            animationSpec = keyframes {
                durationMillis = 375
                0.0f at 0 with LinearOutSlowInEasing // for 0 - 15 ms
                0.2f at 15 with FastOutLinearInEasing  // for 15 - 75ms
                0.4f at 75 //没有 with 默认为 LinearEasing 风格
                0.4f at 225
            })
        val repeatableValue by animateFloatAsState(targetValue = if (enabled) 0.5f else 1f,
            animationSpec = repeatable(iterations = 3,
                animation = tween(300),
                repeatMode = RepeatMode.Reverse)
        )
        val infiniteRepeatableValue by animateFloatAsState(targetValue = if (enabled) 0.5f else 1f,
            animationSpec = infiniteRepeatable(animation = tween(300),
                repeatMode = RepeatMode.Reverse))
        val snapValue by animateFloatAsState(targetValue = if (enabled) 0.5f else 1f,
            animationSpec = snap(200))
        val easingValue by animateFloatAsState(targetValue = if (enabled) 0.5f else 1f,
            animationSpec = tween(300, easing = CustomEasing)
        )
        Button(onClick = { enabled = !enabled },
            modifier = Modifier
                .fillMaxSize(springValue)
                .background(MaterialTheme.colors.primary)) {
            Text(text = "点击我")
        }

    }

    val CustomEasing = Easing { fraction -> fraction * fraction }


    @Preview(showBackground = true)
    @Composable
    fun DefaultPreview4() {
        ComposeWeatherProjectTheme {
//        Greeting4("Android")
            view()
        }
    }
}